package controller

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"gdfs-service/conf"
	"gdfs-service/constant"
	"gdfs-service/controller/vo"
	"gdfs-service/db"
	"gdfs-service/logcat"
	"github.com/gin-gonic/gin"
	"io"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"
)

// @Summary 获取文件返回[]byte
// @Description 根据文件秘钥放回文件字节数组 []byte
// @Param fileKey query string true "文件秘钥"
// @Tags 文件上传下载接口
// @Success 200 {string} json "{"code": "string","data": {"fileBase64": "string","fileData": "string","fileKey": "string","fileOriginalName": "string","filesize": "string"},"msg": "string","time": 0}"
// @Router /download/getFileByteArray [get]
func GetFileByteArray(c *gin.Context) {
	logcat.Info("#########-------------------------------文件下载GetFileByteArray------------------------------------------")
	c.Writer.Header().Set("content-type", "application/json")
	var downloadvo vo.DownloadVo
	result := vo.NewResultInstance()
	fileKey := c.Query("fileKey")
	logcat.Info("#########--文件秘钥filekey ==", fileKey)
	var fileinfo db.FileInfo
	db.GetDB().Where("file_key = ?", fileKey).First(&fileinfo)
	if fileinfo == (db.FileInfo{}) {
		logcat.Info("###找不到文件秘钥")
		downloadvo.Filesize = ""
		downloadvo.FileKey = ""
		WritedString(c.Writer, false, constant.UNFIND_FILEKEY_ERROR, constant.BussinessErrorType[constant.UNFIND_FILEKEY_ERROR], downloadvo)
		return
	} else {
		s := strings.Split(fileinfo.FilePath, "/")
		filepath := conf.GetStorePath() + s[len(s)-2] + "/" + fileinfo.FileName
		logcat.Info("###下载路径:", filepath)
		//判断文件是否存在
		file, err := os.Open(filepath)
		if err != nil {
			//文件打开错误
			log.Println("###open file err:", err)
			fmt.Println(err)
			downloadvo.Filesize = ""
			downloadvo.FileKey = ""
			WritedString(c.Writer, false, constant.UNFIND_FILE_ERROR, constant.BussinessErrorType[constant.UNFIND_FILE_ERROR], downloadvo)
			return
		}
		defer file.Close()
		info, err := file.Stat()
		if err != nil {
			log.Println("###file.Stat() err:", err)
			downloadvo.Filesize = ""
			downloadvo.FileKey = ""
			WritedString(c.Writer, false, constant.UNFIND_FILE_ERROR, constant.BussinessErrorType[constant.UNFIND_FILE_ERROR], downloadvo)
			return
		}

		filesize := info.Size()
		buffer := make([]byte, filesize)
		file.Read(buffer)
		log.Println("#########返回文件秘钥filekey ==", fileinfo.FileKey)
		downloadvo.Filesize = strconv.FormatInt(filesize, 10)
		downloadvo.FileKey = fileinfo.FileKey
		downloadvo.FileData = buffer
		downloadvo.FileOriginalName = fileinfo.FileOriginalName
		result.SucessDefault(downloadvo)
		WriteString(c.Writer, result)
	}

}

// @Summary 获取文件返回base64
// @Description 根据文件秘钥放回文件base64
// @Param fileKey query string true "文件秘钥"
// @Tags 文件上传下载接口
// @Success 200 {string} json "{"code": "string","data": {"fileBase64": "string","fileData": "string","fileKey": "string","fileOriginalName": "string","filesize": "string"},"msg": "string","time": 0}"
// @Router /v1/download/getFileBase64 [get]
func GetFileBase64(c *gin.Context) {
	logcat.Info("##获取文件base64")
	c.Writer.Header().Set("content-type", "application/json")
	var downloadvo vo.DownloadVo
	result := vo.NewResultInstance()
	fileKey := c.Query("fileKey")
	if fileKey == "" {
		downloadvo.Filesize = ""
		downloadvo.FileKey = ""
		WritedString(c.Writer, false, constant.NOTVALID_ERROR, constant.BussinessErrorType[constant.NOTVALID_ERROR], downloadvo)
		return
	}
	var fileinfo db.FileInfo
	db.GetDB().Where("file_key = ?", fileKey).First(&fileinfo)
	s := strings.Split(fileinfo.FilePath, "/")
	filepath := conf.GetStorePath() + s[len(s)-2] + "/" + fileinfo.FileName
	logcat.Info("###下载路径:", filepath)
	//判断文件是否存在
	file, err := os.Open(filepath)
	if err != nil {
		//文件打开错误
		log.Println(err)
		downloadvo.Filesize = ""
		downloadvo.FileKey = ""
		WritedString(c.Writer, false, constant.UNFIND_FILE_ERROR, constant.BussinessErrorType[constant.UNFIND_FILE_ERROR], downloadvo)
		return
	}
	defer file.Close()
	info, err := file.Stat()
	if err != nil {
		log.Println(err)
		downloadvo.Filesize = ""
		downloadvo.FileKey = ""
		WritedString(c.Writer, false, constant.UNFIND_FILE_ERROR, constant.BussinessErrorType[constant.UNFIND_FILE_ERROR], downloadvo)
		return
	}

	filesize := info.Size()
	buffer := make([]byte, filesize)
	file.Read(buffer)
	filebase64 := base64.StdEncoding.EncodeToString(buffer)
	downloadvo.Filesize = strconv.FormatInt(filesize, 10)
	downloadvo.FileKey = fileinfo.FileKey
	downloadvo.FileBase64 = filebase64
	downloadvo.FileOriginalName = fileinfo.FileOriginalName
	result.SucessDefault(downloadvo)
	WriteString(c.Writer, result)
}

func SearchFile(c *gin.Context) {
	logcat.Info("##查询文件")
	c.Writer.Header().Set("content-type", "application/json")
	fileKey := c.Query("fileKey")
	var fileinfo db.FileInfo
	db.GetDB().Where("file_key = ?", fileKey).First(&fileinfo)
	s := strings.Split(fileinfo.FilePath, "/")
	filepath := conf.GetStorePath() + s[len(s)-2] + "/" + fileinfo.FileName
	logcat.Info("###下载路径:", filepath)
	//判断文件是否存在
	_, err := os.Open(filepath)
	if err != nil {
		WritedString(c.Writer, false, constant.UNFIND_FILE_ERROR, constant.BussinessErrorType[constant.UNFIND_FILE_ERROR], nil)
		return
	}
	WritedString(c.Writer, true, constant.SUCCESS, constant.BussinessErrorType[constant.SUCCESS], nil)
}

func WriteString(w http.ResponseWriter, data interface{}) {
	bytejson, _ := json.Marshal(data)
	io.WriteString(w, string(bytejson))
}

func WritedString(w http.ResponseWriter, sucess bool, code string, msg string, data interface{}) {
	result := vo.NewResultInstance()
	if sucess {
		result.Sucess(msg, code, data)
	} else {
		result.Fail(msg, code, data)
	}
	bytejson, _ := json.Marshal(result)
	io.WriteString(w, string(bytejson))
}
